import { EventEmitter } from "events";
import { IGlobal } from "../../../entity/Global";

declare var global: IGlobal;
const HeartTime = 20000;
/**
 * socket客户端连接控制类
 */
export class SocketClient extends EventEmitter {
    static Link_Count = 0;
    private _id: string = '';
    private _key: string = '';
    private _ws: any;
    private _updateTime: number = 0;
    private _timeId: any = 0;
    private _ip:string;
    private _port:number;
    constructor(ws, key,ip:string,port:number) {
        super();
        this._key = key;
        this._id = "L" + (++SocketClient.Link_Count);
        this.setTo(ws,ip,port);
    }

    public setTo(ws,ip:string,port:number) {
        if (this._ws) {
            this._ws.close();
            this._ws.removeAllListeners();
        }
        this._ip=ip;
        this._port=port;
        this._ws = ws;
        var _self = this;
        ws.on('message', (e) => {
            _self._onMessage(e);
        });
        ws.on('close', (e) => {
            _self._onClose(e);
        });
        ws.on('error', (e) => {
            _self.emit("error", e);
        });
        // this.send({ cmd: "connect", key: this._key });
        this._updateTime = Date.now();
        if (!this._timeId) {
            this._timeId = setInterval(this.checkHeart.bind(this), 10000);
        }
    }

    public get id(): string {
        return this._id;
    }

    public get ip() {
        return this._ip;
    }

    public get port(){
        return this._port;
    }

    public get key(): string {
        return this._key;
    }

    public send(d: Buffer | string) {
        if (!d) return;
        var msg=d;
        // global.log.trace(`发送${this._id}:${msg}`)
        try {
            this._ws.send(msg);
        } catch (e) {
            console.error(e);
        }
    }

    // public sendCmd(cmd: string, data: any, id: number = 0) {
    //     this.send({ cmd: cmd, data: data, id: id });
    // }

    public checkHeart() {
        if (Date.now() - this._updateTime > HeartTime) {
            this._close();
        }
    }

    private _stopHeart() {
        if (this._timeId) {
            clearInterval(this._timeId);
        }
        this._timeId = null;
    }

    public close() {
        this._close();
    }

    private _onMessage(d) {
        this._updateTime = Date.now();
        // if (d == "heart") return;
        // global.log.trace(`收到${this._id}:${JSON.stringify(d)}`);
        this.emit("message", this._id, d, this);
    }

    private _onClose(e) {
        this._ws=null;
        this._close();
    }

    private _close() {
        this._stopHeart();
        if (this._ws) {
            this._ws.close(4001, "tick");
            this._ws.removeAllListeners();
        }
        this._ws = null;
        this.emit("close", this._id);
    }
}